package ar.com.quickmart.connectivity;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

public class WebServiceBase {

	// Variables para llamados de webservices
	private static final String serverIP = "192.168.1.3";
	private static final String serverPort = "8080";
	private static final String NAMESPACE = "http://webservices.quickMart.com.ar/";
    private static final String URL = "http://" + serverIP + ":" + serverPort + "/ws/WSAndroidApp?wsdl";
    
    /**
     * 
     * callWebService
     * 
     * Realiza el llamado al webservice y devuelve el resultado
     * 
     * @param methodName		Nombre del metodo o web service
     * @param parameters		parametros que se envian al web service
     * @return					Devuelve un SoapPrimitive si es un tipo de dato primitivo (String, boolean,...) o
     * 							un List<SoapObject> si devuelve beans.
     * 							null si no hay resultados.
     * @throws Exception
     */
   	protected static Object callWebService(String methodName, PropertyInfo... parameters) throws Exception {

		// Defino para este webservice en particular
		final String SOAP_ACTION = "\"http://" + serverIP + ":" + serverPort + "/ws/" + methodName + "\"";	// Tiene que ir quoteado !!
	    final String METHOD_NAME = methodName;
	    Object result = null;
		
	    // Creo request
	    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
	    
	    // Le agrego los parametros
	    for(PropertyInfo param : parameters) {
	    	request.addProperty(param);
	    }
	    
	    // Create envelope
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = false;
        
        // Set output SOAP object
        envelope.setOutputSoapObject(request);
        
        // Create HTTP call object
        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

        try	{
            // LLamada al webservice
            androidHttpTransport.call(SOAP_ACTION, envelope);
            
            // Obtengo la respuesta
            Object response = (Object) envelope.getResponse();
            
            // Asigno la respuesta a resultado
            if(response != null) {
            	
            	// Verifico el tipo de dato devuelto de acuerdo a su clase
            	// ACLARACION: Se supone que no se recibe un vector<> o array[] de tipos de
            	// datos primitivos !!!!!!!!!!!!!!!!!!
            	
            	// Si es un tipo de dato primitivo, como String, long, boolean.. lo devuelvo
            	if(response.getClass() == SoapPrimitive.class) {
                	result = response;
                }
            	// Si es UNICO bean recibido, es un SoapObject y lo devuelvo en forma de lista con un elemento,
            	// para que la funcion que lo reciba, lo haga con una lista independientemente de si es uno o mas resultados
                else if(response.getClass() == SoapObject.class) {
                	
                	// Creo la lista para devolver
                	List<SoapObject> results = new ArrayList<SoapObject>();
                	
                	// Casteo el elemento y lo meto en lista
                	SoapObject resp = (SoapObject) response;
                	results.add(resp);
                	
                	return results;
                }
            	
            	// Si son mas elememntos, los mando a una lista y la devuelvo
                else if(response.getClass() == Vector.class) {
                	
                	// Casteo a vector
                	Vector<Object> newResponse = (Vector<Object>) response;
                	
                	// Creo la lista para devolver
                	List<Object> results = new ArrayList<Object>();
                	
                	// Casteo el elemento y lo meto en lista
                	for(Object obj : newResponse) {
	                	results.add(obj);
                	}
                	
                	return results;
                }
            }
            else {
            	result = null;
            }
        }
        // TODO: Distinguir entre tipos de excepciones, por ejemplo, si no hay conexion, etc
        catch(Exception ex)	{
        	
        	// Muestro excepcion por el log
        	ex.printStackTrace();
        	
        	// Devuelvo la excepcion
        	throw ex;        	
        }
	    
		return result;
	}
    
}
